package com.onehouse.trigger.http;

import com.onehouse.api.dto.checkIn.CheckInOrderDTO;
import com.onehouse.api.dto.checkIn.CheckInStatusDTO;
import com.onehouse.api.dto.checkIn.CheckInSubOrderDTO;
import com.onehouse.domain.checkIn.model.entity.CheckInBill;
import com.onehouse.domain.checkIn.model.entity.CheckInRoom;
import com.onehouse.domain.checkIn.model.entity.CheckInRooms;
import com.onehouse.domain.checkIn.model.valobj.*;
import com.onehouse.domain.checkIn.service.ICheckInService;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.onehouse.types.constants.AjaxResult;

import java.util.ArrayList;

@RestController
@RequestMapping("/check-in")
public class CheckInController {

    @Autowired
    private ICheckInService checkInService;

    @PostMapping("/start-check-in")
    @Operation(summary = "办理入住登记", description = "用于初始化表单")
    public AjaxResult startCheckIn(@RequestBody CheckInOrderDTO checkInOrderDTO) {
        try {
            return AjaxResult.success(this.convertToCheckInOrderDTO(checkInService.startCheckin(this.convertToCheckInRooms(checkInOrderDTO))));
        } catch (RuntimeException e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @PostMapping("/update")
    @Operation(summary = "传入表单数据，用于更新界面", description = "包括填表单时动态的数值运算")
    public AjaxResult update(@RequestBody CheckInOrderDTO checkInOrderDTO) {
        return AjaxResult.success(this.convertToCheckInOrderDTO(checkInService.update(this.convertToCheckInRooms(checkInOrderDTO))));
    }

    @GetMapping("refresh")
    @Operation(summary = "刷新表单数据", description = "不用传入数据，单纯获得当前登记入住表")
    public AjaxResult refresh() {
        try {
            return AjaxResult.success(this.convertToCheckInOrderDTO(checkInService.refresh()));
        } catch (RuntimeException e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @PostMapping("/create-payment")
    @Operation(summary = "进入支付", description = "前端向后端发起支付申请，用于创建支付单，返回入住单单号，后续可根据入住单单号开展支付业务")
    public AjaxResult createPayment() {
        try {
            String checkInOrderId = checkInService.createPayment();
            return AjaxResult.success(checkInOrderId);
        } catch (RuntimeException e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    @PostMapping("/terminate-check-in")
    @Operation(summary = "终止登记入住", description = "清空表单")
    public AjaxResult terminateCheckIn() {
        try {
            checkInService.clear();
            return AjaxResult.success();
        } catch (RuntimeException e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    // TODO 可以考虑放置在另外一个Controller里面
    // TODO 也可以不用轮询，利用前端axios的特性
    // TODO 轮询询问checkInService中的cashPaymentId（现金支付）
    // TODO 轮询询问checkInService中的aliPaymentId和相对应的支付二维码

    /**
     * 将CheckInOrderDTO转换为CheckInRooms
     */
    private CheckInRooms convertToCheckInRooms(CheckInOrderDTO dto) {

        CheckInRooms checkInRooms = new CheckInRooms();
        ArrayList<CheckInRoom> checkInRoomList = new ArrayList<>();

        // 转换子订单
        for (CheckInSubOrderDTO subOrderDTO : dto.getSubOrders()) {
            CheckInRoom checkInRoom = new CheckInRoom();
            
            // 设置基本信息
            checkInRoom.setCheckInDate(subOrderDTO.getCheckInDate());
            checkInRoom.setCheckOutDate(subOrderDTO.getCheckOutDate());
            
            // 转换房间信息
            Room room = new Room();
            room.setRoomNumber(subOrderDTO.getRoom().getRoomNumber());
            room.setRoomTypeId(subOrderDTO.getRoom().getRoomTypeId());
            checkInRoom.setRoom(room);
            
            // 转换客户信息
            ArrayList<Customer> customerList = new ArrayList<>();
            for (CheckInSubOrderDTO.Customer customerDTO : subOrderDTO.getCustomers()) {
                Customer customer = new Customer();
                customer.setName(customerDTO.getName());
                customer.setIdCard(customerDTO.getIdCard());
                customerList.add(customer);
            }
            checkInRoom.setCustomerList(customerList);
            
            // 转换账单信息
            CheckInBill checkInBill = new CheckInBill();

            RoomRate roomRate = new RoomRate();
            roomRate.setAmount(subOrderDTO.getBill().getRate());
            checkInBill.setRoomRate(roomRate);
            
            RoomDeposit roomDeposit = new RoomDeposit();
            roomDeposit.setAmount(subOrderDTO.getBill().getDeposit());
            checkInBill.setRoomDeposit(roomDeposit);

            checkInRoom.setCheckInBill(checkInBill);
            checkInRoomList.add(checkInRoom);
        }
        
        checkInRooms.setCheckInRoomList(checkInRoomList);
        
        return checkInRooms;
    }

    /**
     * 将CheckInRooms转换为CheckInOrderDTO
     */
    private CheckInOrderDTO convertToCheckInOrderDTO(CheckInRooms checkInRooms) {
        CheckInOrderDTO dto = new CheckInOrderDTO();
        ArrayList<CheckInSubOrderDTO> subOrders = new ArrayList<>();

        dto.setStatus(CheckInStatusDTO.valueOf(checkInRooms.getCheckInStatus().toString()));
        dto.setTotalAmount(checkInRooms.getTotalAmount());  //后端向前端才会有这个数据
        
        for (CheckInRoom checkInRoom : checkInRooms.getCheckInRoomList()) {
            CheckInSubOrderDTO subOrder = new CheckInSubOrderDTO();
            
            // 设置基本信息
            subOrder.setCheckInDate(checkInRoom.getCheckInDate());
            subOrder.setCheckOutDate(checkInRoom.getCheckOutDate());
            
            // 转换房间信息
            CheckInSubOrderDTO.Room roomDTO = new CheckInSubOrderDTO.Room();
            roomDTO.setRoomNumber(checkInRoom.getRoom().getRoomNumber());
            roomDTO.setRoomTypeId(checkInRoom.getRoom().getRoomTypeId());
            subOrder.setRoom(roomDTO);
            
            // 转换客户信息
            ArrayList<CheckInSubOrderDTO.Customer> customers = new ArrayList<>();
            for (Customer customer : checkInRoom.getCustomerList()) {
                CheckInSubOrderDTO.Customer customerDTO = new CheckInSubOrderDTO.Customer();
                customerDTO.setName(customer.getName());
                customerDTO.setIdCard(customer.getIdCard());
                customers.add(customerDTO);
            }
            subOrder.setCustomers(customers);
            
            // 转换账单信息
            CheckInSubOrderDTO.Bill billDTO = new CheckInSubOrderDTO.Bill();
            billDTO.setRate(checkInRoom.getCheckInBill().getRoomRate().getAmount());
            billDTO.setDeposit(checkInRoom.getCheckInBill().getRoomDeposit().getAmount());
            billDTO.setTotal(checkInRoom.getCheckInBill().getTotalAmount());
            subOrder.setBill(billDTO);
            
            subOrders.add(subOrder);
        }
        
        dto.setSubOrders(subOrders);
        return dto;
    }
}
